Prueba técnica¶

Toda vez que un nuevo promotor de ventas entra a la microfinanciera, recibe un curso de inducción para familiarizarse con la misión y visión de la compañía y se les da una capacitación con una duración de 6 meses. En algunas ocasiones, una vez terminado el perido de capacitación, el promotor decide dar por terminada la relación laboral.

Datos:

  • fecha de alta (falta): fecha de ingreso a la empresa
  • sexo
  • edad en años
  • sucursal: sucursal u oficina en la que está asignado el promotor
  • div: división o región a la que pertenece la sucursal.
  • número de ventas: total de ventas acumuladas en tres meses
  • sueldo promedio: pago por las comisiones generadas según el número de ventas
  • antigüedad: antigüedad laboral calculada desde de la fecha de inscripción al seguro Social
  • trabajos previos
  • edo civil
  • experiencia
  • número de hijos
  • escolaridad
  • salario diario anterior
  • rotación: el asesor renunció (N) después de terminar la capacitación o no (C)

¿Qué valor le generarías a la empresa a partir de estos datos? Puedes utilizar la herramienta que desees y contarás con 30 minutos para exponer tus ideas. El formato para presentar también es a tu elección.

Librerias¶

In [ ]:
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
import scipy.stats
import sklearn.metrics
import statsmodels.api as sm
import statsmodels.formula.api as smf
import statsmodels.stats as ss
from sklearn.preprocessing import StandardScaler

Dataframe y características¶

In [ ]:
df = pd.read_csv('PruebaTecnicaAll.csv')

Corrección de datos

In [ ]:
df.NUM_HIJOS.replace(to_replace='sin hijos', value='0', regex=True, inplace=True)
df.NUM_HIJOS.replace(to_replace='mas de 4', value='más de 4', regex=True, inplace=True)

Marco general del dataframe

In [ ]:
df = df.rename(columns={'NUMERO_EMPLEADO': 'Numero',
                        'GENERO': 'Genero',
                        'EDAD': 'Edad',
                        'NUM_HIJOS': 'Hijos',
                        'Antigüedad': 'Antigüedad',
                        'NUM_TRABAJOS_PREVIOS': 'Trabajos anteriores',
                        'F_ALTA': 'Alta',
                        'SUCURSAL' : 'Sucursal',
                        'Div' : 'Division',
                        'NUM_VENTAS' : 'Ventas',
                        'SUELDO_PROM' : 'Sueldo',
                        'SALARIO_DIARIO_ANT': 'Salario Anterior Diario',
                        'NUM_DIAS' : 'Dias',
                        'RENUNCIO': 'Continuo',
                        'Unnamed: 14' : 'Salario Actual Diario'
                        })

Se crea la variable Salario Actual Diario para tener realizar una comparación objetiva de cuánto ganaba anteriormente el empleado.

In [ ]:
df['Salario Actual Diario'] = df['Sueldo']/df['Dias']
In [ ]:
df.dtypes
Out[ ]:
Numero                      object
Genero                      object
Edad                         int64
Hijos                       object
Antigüedad                 float64
Trabajos anteriores        float64
Alta                        object
Sucursal                    object
Division                    object
Ventas                       int64
Sueldo                     float64
Salario Anterior Diario    float64
Dias                         int64
Continuo                    object
Salario Actual Diario      float64
dtype: object
In [ ]:
df.shape
Out[ ]:
(17384, 15)
In [ ]:
df
Out[ ]:
Numero Genero Edad Hijos Antigüedad Trabajos anteriores Alta Sucursal Division Ventas Sueldo Salario Anterior Diario Dias Continuo Salario Actual Diario
0 F10 F 32 0 5.0 1.0 02/01/12 CHIMALISTAC SUR 1 316.41 343.0 45 N 7.031333
1 F100 F 40 0 a 4 NaN NaN 16/01/12 COUNTRY CLUB NORTE 27 19013.76 NaN 281 C 67.664626
2 F1000 M 36 más de 4 22.0 6.0 26/03/12 TOLUCA LERMA SUR 7 4037.13 332.0 185 C 21.822324
3 F10000 F 26 0 0.0 0.0 18/03/14 CD. JUAREZ BARRANCAS NORESTE 13 11831.42 374.0 76 N 155.676579
4 F10001 F 28 0 a 4 11.0 3.0 18/03/14 MONTERREY GUADALUPE NORESTE 1 325.64 237.0 34 N 9.577647
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
17379 F9995 F 33 0 a 4 NaN NaN 18/03/14 COLIMA NORTE SURESTE 8 5807.17 160.0 115 N 50.497130
17380 F9996 F 27 más de 4 NaN NaN 18/03/14 MONTERREY SANTA LUCIA NORESTE 1 1411.09 403.0 58 N 24.329138
17381 F9997 M 40 0 NaN NaN 18/03/14 CHIHUAHUA VILLA NORESTE 3 2387.99 60.0 73 N 32.712192
17382 F9998 F 30 0 a 4 NaN NaN 18/03/14 DURANGO NORESTE 7 3799.08 12.0 86 N 44.175349
17383 F9999 M 44 0 a 4 NaN NaN 18/03/14 MONTERREY LEONES NORESTE 21 20623.58 301.0 141 N 146.266525

17384 rows × 15 columns

Porcentaje de decersión¶

In [ ]:
df.Continuo.value_counts(normalize =True).plot(kind='pie')
Out[ ]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f02869d33a0>
In [ ]:
df.Continuo.value_counts(normalize=True)
Out[ ]:
N    0.700357
C    0.299643
Name: Continuo, dtype: float64

De entrada se logra apreciar que el 70% de los empleados no continua después de la capacitación.

Exploratorio de datos¶

Encontrar correlación entre variables

In [ ]:
sns.pairplot(df, hue='Continuo')
Out[ ]:
<seaborn.axisgrid.PairGrid at 0x7f7efe52aa60>
In [ ]:
f, ax = plt.subplots(figsize=(10, 8))
corr = df.corr()
sns.heatmap(corr, mask=np.zeros_like(corr, dtype=np.bool), cmap=sns.diverging_palette(220, 10, as_cmap=True),
            square=True, ax=ax)
<ipython-input-11-b11b29850ac1>:3: DeprecationWarning: `np.bool` is a deprecated alias for the builtin `bool`. To silence this warning, use `bool` by itself. Doing this will not modify any behavior and is safe. If you specifically wanted the numpy scalar type, use `np.bool_` here.
Deprecated in NumPy 1.20; for more details and guidance: https://numpy.org/devdocs/release/1.20.0-notes.html#deprecations
  sns.heatmap(corr, mask=np.zeros_like(corr, dtype=np.bool), cmap=sns.diverging_palette(220, 10, as_cmap=True),
Out[ ]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f0286975c40>
In [ ]:
corr = df.corr()
corr = (corr)
sns.heatmap(corr,
            xticklabels=corr.columns.values,
            yticklabels=corr.columns.values)
plt.title('Heatmap of Correlation Matrix')
corr
Out[ ]:
Edad Antigüedad Trabajos anteriores Ventas Sueldo Salario Anterior Diario Dias Salario Actual Diario
Edad 1.000000 0.067000 0.047917 0.097661 0.105192 -0.019435 0.120611 0.006989
Antigüedad 0.067000 1.000000 0.768011 0.013818 0.025581 -0.017535 0.020887 0.008860
Trabajos anteriores 0.047917 0.768011 1.000000 0.008409 0.018570 -0.014600 0.016021 0.003522
Ventas 0.097661 0.013818 0.008409 1.000000 0.909293 -0.002646 0.600891 0.347998
Sueldo 0.105192 0.025581 0.018570 0.909293 1.000000 -0.011242 0.578077 0.455808
Salario Anterior Diario -0.019435 -0.017535 -0.014600 -0.002646 -0.011242 1.000000 -0.003768 -0.007059
Dias 0.120611 0.020887 0.016021 0.600891 0.578077 -0.003768 1.000000 -0.203310
Salario Actual Diario 0.006989 0.008860 0.003522 0.347998 0.455808 -0.007059 -0.203310 1.000000

Medidas de tendencia central¶

In [ ]:
df.describe()
Out[ ]:
Edad Antigüedad Trabajos anteriores Ventas Sueldo Salario Anterior Diario Dias Salario Actual Diario
count 17384.000000 15935.000000 15935.000000 17384.000000 17384.000000 15975.000000 17384.000000 17384.000000
mean 34.739301 14.289677 3.520552 10.481477 7997.453572 222.736839 203.439427 48.999330
std 7.809158 8.357312 2.685856 8.428932 7370.217956 186.142087 267.576797 36.232031
min 4.000000 0.000000 0.000000 1.000000 10.000000 0.000000 3.000000 0.072473
25% 29.000000 8.000000 2.000000 3.000000 1793.350000 89.000000 60.000000 21.830323
50% 33.000000 13.000000 3.000000 8.000000 5526.670000 180.000000 105.000000 41.129847
75% 39.000000 19.000000 5.000000 17.000000 12890.962500 306.000000 217.000000 67.136448
max 67.000000 46.000000 25.000000 49.000000 55821.380000 1209.000000 1935.000000 391.193165
In [ ]:
des = df.groupby('Continuo')
des.mean()
Out[ ]:
Edad Antigüedad Trabajos anteriores Ventas Sueldo Salario Anterior Diario Dias Salario Actual Diario
Continuo
C 36.019965 14.564826 3.579256 19.882319 15726.874845 220.691415 485.638510 44.320378
N 34.191376 14.171703 3.495382 6.459384 4690.467501 223.667881 82.702259 51.001191

Limpieza de datos¶

In [ ]:
df.isnull().transpose().pipe(
    lambda df: (
        sns.heatmap(
            data = df
        )
    )
)
Out[ ]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f0286975220>
In [ ]:
df.isnull().sum()
Out[ ]:
Numero                        0
Genero                        0
Edad                          0
Hijos                         0
Antigüedad                 1449
Trabajos anteriores        1449
Alta                          0
Sucursal                   1364
Division                      3
Ventas                        0
Sueldo                        0
Salario Anterior Diario    1409
Dias                          0
Continuo                      0
Salario Actual Diario         0
dtype: int64
In [ ]:
dfd = df.dropna()
In [ ]:
des1 = dfd.groupby('Continuo')
des1.mean()
Out[ ]:
Edad Antigüedad Trabajos anteriores Ventas Sueldo Salario Anterior Diario Dias Salario Actual Diario
Continuo
C 35.989525 14.461359 3.548184 20.130354 15874.954711 220.869413 491.641760 44.160177
N 34.010296 14.061347 3.462999 6.697340 4840.132715 223.417954 83.599421 51.917169
In [ ]:
dfd.Continuo.value_counts(normalize =True).plot(kind='pie')
Out[ ]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f0283957850>
In [ ]:
dfd.Continuo.value_counts(normalize=True)
Out[ ]:
N    0.684581
C    0.315419
Name: Continuo, dtype: float64

Subcojuntos N y C, para empleados que No continuario y los que Continuaron

Al final, se decide dejar los datos originales por pérdida de información

Segementación de subgrupos para la variable de interés¶

In [ ]:
c = df[df["Continuo"]!="N"]
In [ ]:
n = df[df["Continuo"]!="C"]
In [ ]:
c.shape
Out[ ]:
(5209, 16)
In [ ]:
n.shape
Out[ ]:
(12175, 16)
In [ ]:
n.describe()
Out[ ]:
Edad Antigüedad Trabajos anteriores Ventas Sueldo Salario Anterior Diario Dias Salario Actual Diario
count 12175.000000 11153.000000 11153.000000 12175.000000 12175.000000 10978.000000 12175.000000 12175.000000
mean 34.191376 14.171703 3.495382 6.459384 4690.467501 223.667881 82.702259 51.001191
std 7.594431 8.306722 2.665034 5.877072 4879.355451 187.601736 40.881931 39.216242
min 4.000000 0.000000 0.000000 1.000000 10.000000 0.000000 3.000000 0.162338
25% 29.000000 8.000000 2.000000 2.000000 1215.900000 88.000000 50.000000 21.286558
50% 32.000000 12.000000 3.000000 4.000000 2930.720000 180.000000 74.000000 42.296250
75% 38.000000 19.000000 5.000000 9.000000 6556.925000 307.000000 109.000000 70.757461
max 67.000000 46.000000 25.000000 44.000000 47202.300000 1206.000000 179.000000 391.193165
In [ ]:
c.describe()
Out[ ]:
Edad Antigüedad Trabajos anteriores Ventas Sueldo Salario Anterior Diario Dias Salario Actual Diario
count 5209.000000 4782.000000 4782.000000 5209.000000 5209.000000 4997.000000 5209.000000 5209.000000
mean 36.019965 14.564826 3.579256 19.882319 15726.874845 220.691415 485.638510 44.320378
std 8.147638 8.468619 2.733183 5.494217 6350.802028 182.896408 348.334742 27.485226
min 21.000000 0.000000 0.000000 1.000000 46.890000 0.000000 181.000000 0.072473
25% 30.000000 8.000000 2.000000 16.000000 11494.930000 91.000000 238.000000 22.622990
50% 34.000000 13.000000 3.000000 19.000000 15046.090000 178.000000 351.000000 39.048052
75% 41.000000 20.000000 5.000000 23.000000 19332.080000 304.000000 597.000000 60.023136
max 64.000000 44.000000 23.000000 49.000000 55821.380000 1209.000000 1935.000000 216.601429

1. Primera propuesta de generación de valor a la empresa:¶

Análisis de deserción¶

Con base en el análisis de correlación de variables, se observan los siguientes casos donde las variables tienen una aparente correlación asociada con si continúan o no en la empresa.

  1. Ventas vs Sueldo
In [ ]:
sns.jointplot(data=df, x='Sueldo', y='Ventas', hue='Continuo')
Out[ ]:
<seaborn.axisgrid.JointGrid at 0x7f029d7a8040>

Resulta evidente inferir que mientras mayores sean las ventas de un promotor, mayor será el sueldo promedio del mismo, y en este análisis se logra observar que a su vez, la mayoría de los empleados que continúan después de la capacitación tienen sueldos y ventas altas.

  1. Antigüedad vs Trabajos Anteriores
In [ ]:
sns.jointplot(data=df, x='Antigüedad', y='Trabajos anteriores', hue='Continuo')
Out[ ]:
<seaborn.axisgrid.JointGrid at 0x7f02817b1760>

Entre estas dos variables además de correlación, hay causalidad, entre más trabajos haya tenido una persona, por ende tendrá más tiempo de estar inscrito en el seguro social. Observamos también que estos factores no intervienen en si el promotor continúa o no después de la capacitación.

De las correlaciones podemos inferir que los empleados que más venden, son los que tienen un mayor sueldo, y por ende, los que permanecen en la empresa después de la capacitación. Teniendo esto en claro, vale la pena analizar qué otros facores influyen en que un empleado venda más, gane más y por lo tanto continúe en la empresa.

  1. Genero VS ventas, salario promedio y deserción.
In [ ]:
sns.pairplot(df, hue='Genero')
Out[ ]:
<seaborn.axisgrid.PairGrid at 0x7f0283849be0>
In [ ]:
(pd.crosstab(df['Genero'],df['Continuo'],
             normalize='index')
   .plot.bar(stacked=True)
)
Out[ ]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f02838ad2e0>

Podemos observar que no existe una relación entre el género del trabajador y su éxito en ventas, lo que gane y su permanencia en el negocio, el género femenino aventaja por poco al masculiino.

  1. Hijos VS ventas, salario promedio y deserción.
In [ ]:
sns.pairplot(df, hue='Hijos')
Out[ ]:
<seaborn.axisgrid.PairGrid at 0x7f7edc8957c0>
In [ ]:
(pd.crosstab(df['Hijos'],df['Continuo'],
             normalize='index')
   .plot.bar(stacked=True)
)
Out[ ]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f027e99a7f0>

Al igual que en el caso anterior, se logra apreciar que la cantidad de hijos que un empleado tiene, no afecta directamente variables como sus ventas, su salario o su tiempo en la empresa, que son las variables relacionadas directamente con la deserción o no del promotor.

  1. Division VS ventas, salario promedio y deserción.
In [ ]:
sns.pairplot(df, hue='Division')
Out[ ]:
<seaborn.axisgrid.PairGrid at 0x7f7edba049d0>
In [ ]:
(pd.crosstab(df['Division'],df['Continuo'],
             normalize='index')
   .plot.bar(stacked=True)
)
Out[ ]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f027e92dd90>

Nuevamente, no se observa un patrón claro en función de la división a la que el promotor permaneza, al menos en términos de pasar el tiempo de capacitación, pero como logramos apreciar, los empleados que llevan más días son los de las divisiones norte y sur, lo que podría dar una pauta de como incentivar a que los empleados permanezcan más tiempo. La divisón NORTE SURESTE es la que aventaja por poco a las demás.

Segunda propuesta de generacion de valor a la empresa¶

  1. Deserción por edades Con la segmentación de c y n o bien crear una nueva por edades, observar que grupos de edades son los que más desertan en la capacitación. bold text
In [ ]:
conditions = [
    (df['Edad'] <= 20),
    (df['Edad'] > 20) & (df['Edad'] <= 30),
    (df['Edad'] > 30) & (df['Edad'] <= 40),
    (df['Edad'] > 40) & (df['Edad'] <= 50),
    (df['Edad'] > 50) & (df['Edad'] <= 60),
    (df['Edad'] > 60)
    ]

values = ['20', '20_30', '30_40', '40_50', '50_60', '60']

df['Edad_Rango'] = np.select(conditions, values)
In [ ]:
(pd.crosstab(df['Edad_Rango'],df['Continuo'],
             normalize='index')
   .plot.bar(stacked=True)
)
Out[ ]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f027e88e640>
In [ ]:
sns.displot(df, x='Dias', hue = 'Edad_Rango', multiple='stack', log_scale=False)
Out[ ]:
<seaborn.axisgrid.FacetGrid at 0x7f027ea19580>

Aunque las medias de las edades tanto de desertores como de empleados que se quedan es bastante similar, encontramos que el grupo de edad con más promotores que continuan después de la capacitación se encuentra en el rango de entre 40 y 50 años. Se le puede generar valor a la empresa privilegiando la contratación de gente en este rango de edad, pues eso disminuiría la rotación Por otro lado, la mayoría de los promotores de entre 20 y 30 años suelen abandonar después de la capacitación.

Tercera propuesta de generación de valor a la empresa¶

  1. Aumento de salario respecto al anterior Diferencia porcentual entre el trabajo anterior y el trabajo actual entre el número de ventas

Media para todo ek universo

In [ ]:
df['Salario Anterior Diario'].mean()
Out[ ]:
222.73683881064161
In [ ]:
df['Salario Actual Diario'].mean()
Out[ ]:
48.99932965102618
In [ ]:
df['Sueldo'].mean()
Out[ ]:
7997.453572250345

Media para C (continua)

In [ ]:
c['Salario Anterior Diario'].mean()
Out[ ]:
220.69141484890935
In [ ]:
c['Salario Actual Diario'].mean()
Out[ ]:
44.3203782571962
In [ ]:
media_continuo_diario = [c['Salario Anterior Diario'].mean(), c['Salario Actual Diario'].mean()]
In [ ]:
media_continuo = [c['Salario Anterior Diario'].mean(), c['Sueldo'].mean()]

Media para N (no continua)

In [ ]:
n['Salario Anterior Diario'].mean()
Out[ ]:
223.66788121697942
In [ ]:
n['Salario Actual Diario'].mean()
Out[ ]:
51.00119066215228
In [ ]:
media_nocontinuo_diario = [n['Salario Anterior Diario'].mean(), n['Salario Actual Diario'].mean()]
In [ ]:
media_nocontinuo = [n['Salario Anterior Diario'].mean(), n['Sueldo'].mean()]
In [ ]:
plt.plot(media_continuo_diario,'b', media_nocontinuo_diario, 'orange')
plt.show()

En ambos casos, tanto en personal que continua como en el que no, observamos que el salario diario tiende a reducirse, sin embargo observamos que es ligeramente menor tanto anterior como actual para los promotores que siguen en la empresa después de la capacitación.

In [ ]:
plt.plot(media_continuo,'b', media_nocontinuo, 'orange')
plt.show()

Por otro lado, si comparamos las variables directas, es decir, el salario diario anterior directamente con el sueldo actual del promotor (sin dividir entre el número de ventas del mismo) se observa un aumento para ambas, pero es claro que los promotores que continuaron después de la capacitación aumentaron mucho más.

La promotora obtendría valor al mejorar la capacitación, incentivar a los promotores nuevos y fomentar el ambiente para que estos eleven sus ventas, lo que además de lograr retenerlos por más tiempo, aumentaría directamente las ventas de la empresa.

Cuarta propuesta de generación de valor: perspectiva de genero¶

In [ ]:
h = df[df["Genero"]!="F"]
In [ ]:
m = df[df["Genero"]!="M"]
In [ ]:
h.describe()
Out[ ]:
Edad Antigüedad Trabajos anteriores Ventas Sueldo Salario Anterior Diario Dias Salario Actual Diario
count 8198.000000 7533.000000 7533.000000 8198.000000 8198.000000 7595.000000 8198.000000 8198.000000
mean 35.163942 14.173636 3.501527 9.594169 7147.020940 223.412640 170.395096 48.402850
std 7.749664 8.227844 2.658597 8.174942 7007.481793 186.380328 225.509519 36.153378
min 4.000000 0.000000 0.000000 1.000000 10.000000 0.000000 7.000000 0.072473
25% 30.000000 8.000000 2.000000 2.000000 1523.440000 90.000000 57.000000 21.373012
50% 33.000000 13.000000 3.000000 7.000000 4599.550000 182.000000 94.000000 40.604000
75% 39.000000 19.000000 5.000000 16.000000 11419.010000 305.000000 178.000000 66.614764
max 67.000000 46.000000 25.000000 49.000000 51331.000000 1195.000000 1907.000000 391.193165
In [ ]:
m.describe()
Out[ ]:
Edad Antigüedad Trabajos anteriores Ventas Sueldo Salario Anterior Diario Dias Salario Actual Diario
count 9186.000000 8402.000000 8402.000000 9186.000000 9186.000000 8380.000000 9186.000000 9186.000000
mean 34.360331 14.393716 3.537610 11.273351 8756.417944 222.124344 232.929676 49.531655
std 7.842900 8.470845 2.710106 8.572535 7599.916882 185.934900 297.106616 36.295771
min 19.000000 0.000000 0.000000 1.000000 10.000000 0.000000 3.000000 0.168919
25% 28.000000 8.000000 2.000000 3.000000 2109.652500 88.000000 64.000000 22.133486
50% 32.000000 13.000000 3.000000 10.000000 6752.715000 178.000000 115.000000 41.390386
75% 39.000000 20.000000 5.000000 18.000000 13916.197500 307.000000 259.000000 67.874930
max 64.000000 45.000000 23.000000 45.000000 55821.380000 1209.000000 1935.000000 315.663377
In [ ]:
h_dict = {'Antiguedad':h['Antigüedad'].mean(), 'Ventas':h['Ventas'].mean(), 'Sueldo':h['Sueldo'].mean(), 'Dias':h['Dias'].mean()}
h_names = list(h_dict.keys())
h_values = list(h_dict.values())
In [ ]:
h_dict
Out[ ]:
{'Antiguedad': 14.17363600159299,
 'Ventas': 9.594169309587704,
 'Sueldo': 7147.020940473286,
 'Dias': 170.39509636496706}
In [ ]:
m_dict = {'Antiguedad':m['Antigüedad'].mean(), 'Ventas':m['Ventas'].mean(), 'Sueldo':m['Sueldo'].mean(), 'Dias':m['Dias'].mean()}
m_names = list(m_dict.keys())
m_values = list(m_dict.values())
In [ ]:
m_dict
Out[ ]:
{'Antiguedad': 14.393715781956677,
 'Ventas': 11.273350751143044,
 'Sueldo': 8756.41794360984,
 'Dias': 232.92967559329415}

Observamos un mayor número de ventas y de permanencia en la empresa por parte de las promotoras de género femenino. Diversos estudios sugieren que una empresa diversa tiende a ser más prospera, sin embargo es probable que para algunas posiciones en particular un género tenga más éxito que otro, como arroja esta estadística.

Transformación de variables¶

In [ ]:
df.Genero.replace(to_replace='F', value='0', regex=True, inplace=True)
df.Genero.replace(to_replace='M', value='1', regex=True, inplace=True)
In [ ]:
df.Division.replace(to_replace='METROPOLITANA', value='0', regex=True, inplace=True)
df.Division.replace(to_replace='NORESTE', value='1', regex=True, inplace=True)
df.Division.replace(to_replace='NORTE', value='2', regex=True, inplace=True)
df.Division.replace(to_replace='NORTE SURESTE', value='3', regex=True, inplace=True)
df.Division.replace(to_replace='SUR', value='4', regex=True, inplace=True)
In [ ]:
df.Hijos.replace(to_replace='0', value='0', regex=True, inplace=True)
df.Hijos.replace(to_replace='0 a 4', value='1', regex=True, inplace=True)
df.Hijos.replace(to_replace='más de 4', value='2', regex=True, inplace=True)
In [ ]:
df['Salario Anterior Diario'].replace(to_replace='', value='0', regex=True, inplace=True)
df['Trabajos anteriores'].replace(to_replace='', value='0', regex=True, inplace=True)

Modelos de clasificación¶

In [ ]:
from sklearn.model_selection import train_test_split

from sklearn.metrics import accuracy_score
from sklearn.metrics import confusion_matrix

from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC
In [ ]:
X = df.drop('Continuo', axis=1)
labels = df['Continuo']
X_train, X_test, labels_train, labels_test = train_test_split(X, labels, random_state=1, test_size = 0.2)
predictors = ["Ventas","Sueldo", "Edad", "Genero", "Hijos"]

Arbol de decisión¶

In [ ]:
model = DecisionTreeClassifier()
model.fit(X_train[predictors], labels_train)
labels_predict = model.predict(X_test[predictors])
accuracy_score(labels_test, labels_predict)
Out[ ]:
0.8354903652574058
In [ ]:
pd.DataFrame(
    confusion_matrix(labels_test, labels_predict),
    columns=['Predicción continuó', 'Predicción no continuó'],
    index=['Verdadero continuó', 'Verdadero no continuó']
)
Out[ ]:
Predicción continuó Predicción no continuó
Verdadero continuó 729 308
Verdadero no continuó 264 2176

Bosque aleatorio¶

In [ ]:
model = RandomForestClassifier()
model.fit(X_train[predictors], labels_train)
labels_predict = model.predict(X_test[predictors])
accuracy_score(labels_test, labels_predict)
Out[ ]:
0.8754673569168824
In [ ]:
pd.DataFrame(
    confusion_matrix(labels_test, labels_predict),
    columns=['Predicción continuó', 'Predicción no continuó'],
    index=['Verdadero continuó', 'Verdadero no continuó']
)
Out[ ]:
Predicción continuó Predicción no continuó
Verdadero continuó 867 170
Verdadero no continuó 263 2177
In [ ]:
pd.Series(model.feature_importances_, index=predictors).sort_values(ascending=False)
Out[ ]:
Sueldo    0.441245
Ventas    0.422520
Edad      0.103584
Hijos     0.022438
Genero    0.010212
dtype: float64

K-Vecinos más cercanos¶

In [ ]:
model = KNeighborsClassifier()
model.fit(X_train[predictors], labels_train)
labels_predict = model.predict(X_test[predictors])
accuracy_score(labels_test, labels_predict)
Out[ ]:
0.8478573482887547
In [ ]:
pd.DataFrame(
    confusion_matrix(labels_test, labels_predict),
    columns=['Predicción continuó', 'Predicción no continuó'],
    index=['Verdadero continuó', 'Verdadero no continuó']
)
Out[ ]:
Predicción continuó Predicción no continuó
Verdadero continuó 774 263
Verdadero no continuó 266 2174

Regresión logística¶

In [ ]:
model = LogisticRegression()
model.fit(X_train[predictors], labels_train)
labels_predict = model.predict(X_test[predictors])
accuracy_score(labels_test, labels_predict)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-2-f3c4dc3548e7> in <module>
----> 1 model = LogisticRegression()
      2 model.fit(X_train[predictors], labels_train)
      3 labels_predict = model.predict(X_test[predictors])
      4 accuracy_score(labels_test, labels_predict)

NameError: name 'LogisticRegression' is not defined
In [ ]:
model = SVC(kernel='linear')
model.fit(X_train[predictors], labels_train)
labels_predict = model.predict(X_test[predictors])
accuracy_score(labels_test, labels_predict)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-1-c07109b39b6b> in <module>
----> 1 model = SVC(kernel='linear')
      2 model.fit(X_train[predictors], labels_train)
      3 labels_predict = model.predict(X_test[predictors])
      4 accuracy_score(labels_test, labels_predict)

NameError: name 'SVC' is not defined